/*
 * @Author: Yanan Chen
 * @Date: 2021-11-02 13:39:49
 * @LastEditTime: 2021-12-13 13:25:57
 * @LastEditors: Yanan Chen
 * @Description: 
 * @FilePath: \sadwinner\fw\esp32\Src\Hal\hal_spi.c
 * 
 */



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "hal_spi.h"

#define SPI_CS_PIN_SEL  ((1ULL<<DIS_PIN_NUM_CS_OLED) | (1ULL<<DIS_PIN_NUM_CS_EPAPER))

spi_device_handle_t DisSpi;





void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
{
   switch((int)(t->user))
   {
       case SPI_DIS_SEL_OLED:
        gpio_set_level(DIS_PIN_NUM_CS_OLED, 0);
       break;
       case SPI_DIS_SEL_EPAPER:
        gpio_set_level(DIS_PIN_NUM_CS_EPAPER, 0);
       break;
   }
}

void lcd_spi_post_transfer_callback(spi_transaction_t *t)
{
    switch((int)(t->user))
   {
       case SPI_DIS_SEL_OLED:
        gpio_set_level(DIS_PIN_NUM_CS_OLED, 1);
       break;
       case SPI_DIS_SEL_EPAPER:
        gpio_set_level(DIS_PIN_NUM_CS_EPAPER, 1);
       break;
   }
}


void hal_dis_spi_init()
{
    esp_err_t ret;

    gpio_config_t io_conf = {};
     //disable interrupt
    io_conf.intr_type = GPIO_INTR_DISABLE;
    //set as output mode
    io_conf.mode = GPIO_MODE_OUTPUT;
    //bit mask of the pins that you want to set,e.g.GPIO18/19
    io_conf.pin_bit_mask = SPI_CS_PIN_SEL;
    //disable pull-down mode
    io_conf.pull_down_en = 0;
    //disable pull-up mode
    io_conf.pull_up_en = 1;
    //configure GPIO with the given settings
    gpio_config(&io_conf);

    gpio_set_level(DIS_PIN_NUM_CS_OLED, 1);
    gpio_set_level(DIS_PIN_NUM_CS_EPAPER, 1);
    
    spi_bus_config_t buscfg={
        .miso_io_num=DIS_PIN_NUM_MISO,
        .mosi_io_num=DIS_PIN_NUM_MOSI,
        .sclk_io_num=DIS_PIN_NUM_CLK,
        .quadwp_io_num=-1,
        .quadhd_io_num=-1,
        .max_transfer_sz=100, //TODO 
    };
    spi_device_interface_config_t oleddevcfg={
        .clock_speed_hz=80*1000*1000,          
        .mode=3,                                //SPI mode 0
        .spics_io_num=-1,               //CS pin
        .queue_size=7,                          //We want to be able to queue 7 transactions at a time
        .pre_cb=lcd_spi_pre_transfer_callback,  //Specify pre-transfer callback to handle D/C line
        .post_cb = lcd_spi_post_transfer_callback,
    };
    //Initialize the SPI bus
    ret=spi_bus_initialize(VSPI_HOST, &buscfg, 1);
    ESP_ERROR_CHECK(ret);
    //Attach the LCD to the SPI bus
    ret=spi_bus_add_device(VSPI_HOST, &oleddevcfg, &DisSpi);
    ESP_ERROR_CHECK(ret);
}

void DisBusWrite(SPI_DIS_SEL dev,void *data,int len)
{
    esp_err_t ret;
    spi_transaction_t t;
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    t.length=len*8;                     //Command is 8 bits
    t.tx_buffer=data;               //The data is the cmd itself
    t.user=(void*)dev;                //D/C needs to be set to 0
    ret=spi_device_polling_transmit(DisSpi, &t);  //Transmit!
    assert(ret==ESP_OK);            //Should have had no issues.
};










